<!doctype html>
<html itemscope itemtype="http://schema.org/WebPage" lang="zh-cn" class="no-js">
  <head>
    <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.121.1">
<link rel="canonical" type="text/html" href="/docs/contribution-guidelines/">
<meta name="robots" content="noindex, nofollow">


<link rel="shortcut icon" href="/favicons/favicon.ico" >
<link rel="apple-touch-icon" href="/favicons/apple-touch-icon-180x180.png" sizes="180x180">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/android-36x36.png" sizes="36x36">
<link rel="icon" type="image/png" href="/favicons/android-48x48.png" sizes="48x48">
<link rel="icon" type="image/png" href="/favicons/android-72x72.png" sizes="72x72">
<link rel="icon" type="image/png" href="/favicons/android-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicons/android-144x144.png" sizes="144x144">
<link rel="icon" type="image/png" href="/favicons/android-192x192.png" sizes="192x192">

<title>参与社区 | SOFAServerless</title>
<meta name="description" content="">
<meta property="og:title" content="参与社区" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="/docs/contribution-guidelines/" />

<meta itemprop="name" content="参与社区">
<meta itemprop="description" content=""><meta name="twitter:card" content="summary"/><meta name="twitter:title" content="参与社区"/>
<meta name="twitter:description" content=""/>




<link rel="preload" href="/scss/main.min.526354c4efc1a4747972ed64c3be00f7db62aec5f0a3e6ae42052f97e2675d86.css" as="style">
<link href="/scss/main.min.526354c4efc1a4747972ed64c3be00f7db62aec5f0a3e6ae42052f97e2675d86.css" rel="stylesheet" integrity="">

<script
  src="https://code.jquery.com/jquery-3.6.3.min.js"
  integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
  crossorigin="anonymous"></script>
<link rel="stylesheet" href="/css/prism.css"/>
<link href="/img/logo.svg" rel="icon" type="image/svg">
<link href="/search/pagefind-ui.css" rel="stylesheet">
<script src="/search/pagefind-ui.js" type="text/javascript"></script>

<script>
    window.addEventListener('DOMContentLoaded', (event) => {
        new PagefindUI({ element: ".td-search" });
    });
</script>


<script>
var doNotTrack = false;
if (!doNotTrack) {
	window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
	ga('create', 'G-DZ8Q3F0GZ7', 'auto');
	
	ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>

<script async src="https://www.googletagmanager.com/gtag/js?id=G-DZ8Q3F0GZ7"></script>
<script>
var doNotTrack = false;
if (!doNotTrack) {
	window.dataLayer = window.dataLayer || [];
	function gtag(){dataLayer.push(arguments);}
	gtag('js', new Date());
	gtag('config', 'G-DZ8Q3F0GZ7');
}
</script>
  </head>
  <body class="td-section">
    <header>
      <nav class="td-navbar navbar-dark js-navbar-scroll">
<div class="container-fluid flex-column flex-md-row">
  <a class="navbar-brand" href="/"><span class="navbar-brand__logo navbar-logo"><svg width="26" height="29" viewBox="0 0 26 29" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient x1="52.6662558%" y1="95.7312514%" x2="35.7492678%" y2="11.0078657%" id="linearGradient-wxw43fh1xd-1"><stop stop-color="#9822e4" offset="0"/><stop stop-color="#e643fa" offset="86.0585504%"/><stop stop-color="#f876ff" offset="100%"/></linearGradient><path d="M15.9275871 1.54432572 15.936122 1.5594269 15.9445709 1.57457632 5.01248933 7.79418913 7.699 9.304l8.8412359-4.72420311.8668497-.49490764C17.4171462 4.0791454 17.4272394 4.07345885 17.4373647 4.06782987c1.474137-.81952243 3.3335154-.28885241 4.1530379 1.18528466L10.875 11.088l2.864 1.609 8.843271-5.6213813c1.1038914-.6292563 2.5021428-.23250173 3.1230817.88617614C25.8984381 8.30965565 25.9998668 8.70204694 25.9998668 9.10116416V19.9436637c0 1.3476373-1.002317 2.484932-2.3392704 2.6542897L22.9421516 22.6889619V10.4257286L20.457252 12.0257475 20.457758 23.6880152c0 1.2665471-1.0267393 2.2932864-2.2932864 2.2932864H17.59115L17.590252 13.8727475 15.106 15.473 15.1067564 27.0588825c0 1.0695936-.855616100000001 1.9366704-1.911072 1.9366704C12.8696714 28.9955529 12.5490782 28.9110348 12.2643947 28.7500365L1.63270516 23.3171586C.159863707 22.5645249-.423980046 20.7604209.328653641 19.2875794L.372104915 19.2057013 12.0490412 25.0797183 12.049 22.086 1.98952173 16.7675786C.51279311 15.9867912-.0513787599 14.1567129.729408593 12.6799843L.744416289 12.6519572.759717752 12.6240895 12.049 18.593 12.0490412 15.2566254 1.7391964 9.45898637C1.44132502 9.2850324 1.19527431 9.0328708 1.02697438 8.72907568c-.516688418-.93266477-.189466545-2.11320819.7308705-2.63681754C6.19445786 3.56812633 9.52191759 1.67502747 11.7402241.412961569L11.7628911.400065593c1.4660277-.834070345 3.3306257-.321767634 4.164696 1.144260127z" id="path-wxw43fh1xd-2"/><linearGradient x1="50.6099966%" y1="31.6743333%" x2="50.2419846%" y2="73.0702907%" id="linearGradient-wxw43fh1xd-4"><stop stop-color="#8200b5" offset="0"/><stop stop-color="#8200b5" stop-opacity="0" offset="100%"/></linearGradient><linearGradient x1="50.6028666%" y1="31.6743333%" x2="50.2391561%" y2="73.0702907%" id="linearGradient-wxw43fh1xd-5"><stop stop-color="#8200b5" offset="0"/><stop stop-color="#8200b5" stop-opacity="0" offset="100%"/></linearGradient><linearGradient x1="90.8235257%" y1="50%" x2="3.24041867%" y2="52.9415572%" id="linearGradient-wxw43fh1xd-6"><stop stop-color="#dd3ff7" stop-opacity="0" offset="0"/><stop stop-color="#ca23e4" offset="100%"/></linearGradient><linearGradient x1="74.3272776%" y1="35.8586031%" x2="19.6895996%" y2="19.3309621%" id="linearGradient-wxw43fh1xd-7"><stop stop-color="#b800d1" stop-opacity="0" offset="0"/><stop stop-color="#ae00c5" offset="100%"/></linearGradient><linearGradient x1="97.0070676%" y1="71.8003287%" x2="11.3661868%" y2="30.5044309%" id="linearGradient-wxw43fh1xd-8"><stop stop-color="#940ec7" offset="0"/><stop stop-color="#c435f0" stop-opacity="0" offset="100%"/></linearGradient></defs><g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="首页" transform="translate(-24.000000, -18.000000)"><g id="编组-4" transform="translate(24.000133, 16.000000)"><g id="路径-6-copy-2" transform="translate(0.000000, 2.004447)"><mask id="mask-wxw43fh1xd-3" fill="#fff"><use xlink:href="#path-wxw43fh1xd-2"/></mask><use id="Mask" fill="url(#linearGradient-wxw43fh1xd-1)" fill-rule="nonzero" xlink:href="#path-wxw43fh1xd-2"/><path d="M12.0490412 15.2684078 13.03943 15.5167092C14.3279076 16.0478608 15.1686754 17.3038563 15.1686754 18.6975193V18.7421449v9.047164l-3.1196342-1.4070083V15.2684078z" id="Path-114-Copy-2" fill="url(#linearGradient-wxw43fh1xd-4)" opacity=".69047619" mask="url(#mask-wxw43fh1xd-3)"/><path d="M22.9421516 10.4227424 23.8594661 10.2542707C24.8889759 10.219744 25.7876765 10.946368 25.9694916 11.9602841L26.0763097 12.5559692 26.0617858 22.9064645l-3.1196342-1.4070082V10.4227424z" id="Path-114-Copy-2" fill="url(#linearGradient-wxw43fh1xd-5)" opacity=".69047619" mask="url(#mask-wxw43fh1xd-3)"/><polygon id="Path-41" fill="url(#linearGradient-wxw43fh1xd-6)" mask="url(#mask-wxw43fh1xd-3)" points="7.6326499 9.31647968 11.9297751 6.77228295 14.9765833 9.31647968 10.7681311 11.1500753"/><path d="M6.16852974 12.7326226C8.05429918 13.6181711 7.86496926 14.83948 8.18831704 15.006813 8.70089861 15.2720748 9.14143095 17.098905 9.86115602 17.1695013 10.6949216 17.2512836 11.6478081 10.8552079 10.3936906 10.4556578 9.48069361 10.1647855 7.32719679 9.49121213 3.93320016 8.43493769c-.63204609 1.86851711.11306377 3.30107871 2.23532958 4.29768491z" fill="url(#linearGradient-wxw43fh1xd-7)" mask="url(#mask-wxw43fh1xd-3)" transform="translate(7.357416, 12.802608) rotate(-347.000000) translate(-7.357416, -12.802608)"/><polygon id="Path-43" fill="url(#linearGradient-wxw43fh1xd-8)" mask="url(#mask-wxw43fh1xd-3)" points="12.0699788 18.5615749 6.27140769 15.1359473 5.30588708 19.0963147 12.0699788 22.1120507"/></g></g></g></g></svg></span><span class="navbar-brand__name">SOFAServerless</span></a>
  <div class="td-navbar-nav-scroll ms-md-auto" id="main_navbar">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" href="/home/"><span>首页</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link active" href="/docs/"><span>产品文档</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/blog/"><span>最新信息</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/community/"><span>参与社区</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/user-cases/"><span>用户案例</span></a>
      </li>
      <li class="nav-item dropdown d-none d-lg-block">
        <div class="dropdown">
  <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">中文</a>
  <ul class="dropdown-menu">
    <li><a class="dropdown-item" href="/no/"></a></li>
    </ul>
</div></li>
      </ul>
  </div>
  <div class="d-none d-lg-block">
    <div class="td-search">
  <div class="td-search__icon"></div>
  <input type="search" class="td-search__input form-control td-search-input" placeholder="站内搜索…" aria-label="站内搜索…" autocomplete="off">
</div>

  </div>
</div>
</nav>
    </header>
    <div class="container-fluid td-outer">
      <div class="td-main">
        <div class="row flex-xl-nowrap">
          <main class="col-12 col-md-9 col-xl-8 ps-md-5" role="main">
            




<div class="td-content">
<div class="pageinfo pageinfo-primary d-print-none">
<p>
这是本节的多页打印视图。
<a href="#" onclick="print();return false;">点击此处打印</a>.
</p><p>
<a href="/docs/contribution-guidelines/">返回本页常规视图</a>.
</p>
</div>



<h1 class="title">参与社区</h1>





    <ul>
    
  
  
  
  

  
    
    
	
<li>1: <a href="#pg-e29f40edf90bd16bb849d278394baf42">开放包容理念</a></li>


    
  
    
    
	
<li>2: <a href="#pg-602e76c3bdfe995632399d8611c22fa3">交流渠道</a></li>


    
  
    
    
	
<li>3: <a href="#pg-a473df27e2a59f4a48f7ec005f1be08d">贡献社区</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>3.1: <a href="#pg-2116f3408dfc680cc19d506d77f5894a">本地开发测试</a></li>


    
  
    
    
	
<li>3.2: <a href="#pg-5726ff7fce2c3ff40a2cd82591c376cc">完成第一次 PR 提交</a></li>


    
  
    
    
	
<li>3.3: <a href="#pg-6c5458a163d621b3a719a2d5b3973530">文档、Issue、流程贡献</a></li>


    
  
    
    
	
<li>3.4: <a href="#pg-d890a1e9140aca7ee684208abba11a5f">组织会议和运营布道</a></li>


    
  

    </ul>
    
  
    
    
	
<li>4: <a href="#pg-20720f61569788d3fa4a197db902e640">社区角色与晋升</a></li>


    
  
    
    
	
<li>5: <a href="#pg-00e955e7b325b37beabf9dc83947c176">SOFAArk 技术文档</a></li>


    
    <ul>
        
  
  
  
  

  

    </ul>
    
  
    
    
	
<li>6: <a href="#pg-9ae993d6fa8ac20662cf30a0e33bd534">Arklet 技术文档</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>6.1: <a href="#pg-44f8de035a733443de71918dd607b8ae">Arklet 架构设计与接口设计</a></li>


    
  
    
    
	
<li>6.2: <a href="#pg-ca0da12fe622ea86b46a675b1cf7ff9e">如何发布 Arklet 版本</a></li>


    
  

    </ul>
    
  
    
    
	
<li>7: <a href="#pg-9f7246557f3988e5591410a2c92f379e">ModuleController 技术文档</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>7.1: <a href="#pg-72b8455792d08674da639fa21b8e66ae">ModuleController 架构设计</a></li>


    
  
    
    
	
<li>7.2: <a href="#pg-be4b5c4491d910c089a03f3bd6b4ec7b">CRD 模型设计</a></li>


    
  
    
    
	
<li>7.3: <a href="#pg-339ad39102ec6d572f675d168eb0a6c2">核心代码结构</a></li>


    
  
    
    
	
<li>7.4: <a href="#pg-de7e40f637d5e11c931b8c9e41910f4d">模块生命周期</a></li>


    
  
    
    
	
<li>7.5: <a href="#pg-4c6a73428cd292db6a65b7e3740abdd4">核心流程时序图</a></li>


    
  

    </ul>
    
  
    
    
	
<li>8: <a href="#pg-db0fd3436760ca9f36ce5775358861d3">Arkctl 技术文档</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>8.1: <a href="#pg-17a1474bf0b4f08b2afd73c908fb081d">Arkctl 技术文档</a></li>


    
  

    </ul>
    
  
    
    
	
<li>9: <a href="#pg-c5379127fb28ac273198b2c05d133831">多模块运行时适配或最佳实践</a></li>


    
    <ul>
        
  
  
  
  

  
    
    
	
<li>9.1: <a href="#pg-e8336cb2ec84a57eea63b09a2d517063">log4j2 的多模块化适配</a></li>


    
  
    
    
	
<li>9.2: <a href="#pg-fce299658e201c9a561eaab5974c0199">ehcache 的多模块化最佳实践</a></li>


    
  

    </ul>
    
  

    </ul>


<div class="content">
      
</div>
</div>


  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-e29f40edf90bd16bb849d278394baf42">1 - 开放包容理念</h1>
    
	<h2 id="核心价值观">核心价值观</h2>
<p>SOFAServerless 社区的核心价值观是 <strong>“开放” 和 “包容”</strong>。社区里所有的用户、开发者<strong>完全平等</strong>，体现在如下几个方面：</p>
<ol>
<li>
<p>社区参考了 Apache 开源项目的运作方式，对社区做出<strong>任意贡献</strong>的同学，尤其是<strong>非代码贡献</strong>的同学（文档、官网、Issue 回复、运营布道、发展建议等），都是我们的 Contributor，都有机会成为社区的 Committer 甚至是 PMC（Project Management Committee）成员。</p>
</li>
<li>
<p>社区所有的 OKR、RoadMap、讨论、会议、技术方案等都是<strong>完全开放的</strong>，所有人都可以看见，并且都可以参与其中，社区会认证倾听、考虑大家的所有建议和意见，一旦采纳就会确保执行落地。希望大家带着<strong>无所顾虑</strong>、求同<strong>尊异</strong>的心态参与 SOFAServerless 社区。</p>
</li>
<li>
<p>社区不限地域国籍，所有源代码必须是<strong>英文注释</strong>确保大家都能理解，官网也是中英文双语。所有微信群、钉钉群、GitHub Issues 讨论都可以是<strong>中英双语</strong>。但由于当前我们主要聚焦在国内用户，因此大部分文档暂时只有中文版，未来会提供英文版。</p>
</li>
</ol>
<h2 id="2023-年-okr">2023 年 OKR</h2>
<h3 id="o1--打造社区健康有行业影响力的-serverless-开源产品">O1  打造社区健康、有行业影响力的 Serverless 开源产品</h3>
<h4 id="kr1--新增-10-个-contributors年底-openrank-指数--15当前-5活跃度--50当前-44">KR1  新增 10 个 Contributors，年底 OpenRank 指数 &gt; 15（当前 5）、活跃度 &gt; 50（当前 44）</h4>
<p><strong>KR1.1</strong>  完成 5 次布道和 5 次文章分享，触达 200 家企业，深度交流 30+ 企业。<br />
<strong>KR1.2</strong>  形成完善的社区共建机制（包括 Issue 管理、文档、问题响应、培养与晋升机制），发布 2+ 培训课程与产品手册，共建开发者可在一周内上手，开发总吞吐率达到 20+ Issues/周。</p>
<h4 id="kr2--新增-5-家企业在生产环境使用或完成试点接入当前新增-13-家企业参与社区">KR2  新增 5 家企业在生产环境使用或完成试点接入（当前新增 1），3 家企业参与社区</h4>
<p><strong>KR2.1</strong>  产出初步行业分析报告，帮助定位适用不同场景的重点企业对象。<br />
<strong>KR2.2</strong>  5 家企业生产真实使用或完成试点接入，3 家企业参与社区，覆盖 3 个场景并沉淀 3+ 用户案例。</p>
<h3 id="o2--打造技术先进效果显著的降本增效解决方案">O2  打造技术先进、效果显著的降本增效解决方案</h3>
<h4 id="kr1--落地模块化技术实现机器减少-30部署验证耗时降低至-30-秒需求交付效率提升-50">KR1  落地模块化技术实现机器减少 30%、部署验证耗时降低至 30 秒、需求交付效率提升 50%</h4>
<p><strong>KR1.1</strong>  搭建 1 分钟快速试用平台，完善的文档、官网与配套支持，用户可在 10 分钟完成一个模块拆分。<br />
<strong>KR1.2</strong>  完成 20 种中间件和三方包治理，同时形成多应用与热卸载评测和自动检测标准。<br />
<strong>KR1.3</strong>  模块具备热部署启动耗时降低至 10 秒级，多模块具备合并部署资源减少 30%，同时让用户需求交付效率提升 50%。<br />
<strong>KR1.4</strong>  落地开源版 Arklet，支持 SOFABoot 和 SpringBoot。提供运维管道、指标采集、模块生命周期管理、多模块运行环境、Bean 与服务发现及调用能力。<br />
<strong>KR1.5</strong>  落地研发工具 ArkCtl，具备快速开发验证、灵活部署（合并与独立部署）、模块低成本拆分改造能力。</p>
<h4 id="kr2--运维调度-10-版本上线全链路高频端到端测试用例成功率-999自身端到端耗时-p90--500ms">KR2  运维调度 1.0 版本上线。全链路高频端到端测试用例成功率 99.9%，自身端到端耗时 P90 &lt; 500ms</h4>
<p><strong>KR2.1</strong>  上线基于 K8S Operator 的开源版运维调度能力，至少具备发布、回滚、下线、扩缩容、替换、副本保持、2+ 调度策略、模块流控、部署策略、对等和非对等运维能力。<br />
<strong>KR2.2</strong>  建设开源版 CI 和 25+ 高频端到端测试用例，不断打磨并推动端到端 P90 耗时 &lt; 500ms、所有预演成功率&gt; 99.9%、单测覆盖率达到行 &gt; 80% 分支 &gt; 60%（通过率 100%）。</p>
<h4 id="kr3--开源版自动伸缩初步上线模块具备人工画像和分时伸缩能力">KR3  开源版<strong>自动伸缩初步</strong>上线，模块具备人工画像和分时伸缩能力</h4>
<h2 id="roadmap">RoadMap</h2>
<ul>
<li>2023.08  完成 SOFABoot 完整的部署功能验证，产出兼容性 Benchmark 基线。</li>
<li>2023.09  发布基础运维和调度系统 ModuleController 0.5 版本。</li>
<li>2023.09  发布研发运维工具 Arkctl 与 Arklet 0.5 版本。</li>
<li>2023.09  官网和完整用户手册上线。</li>
<li>2023.10  新增 2+ 公司使用。</li>
<li>2023.11  支持 SpringBoot 完整能力和 5+ 社区常用中间件。</li>
<li>2023.11  SOFAServerless 1.0 版本上线（ModuleController、Arkctl、Arklet、SpringBoot 兼容）。</li>
<li>2023.12  SOFAServerless 1.1 版本上线（包括基础自动伸缩、模块基础拆分工具、20+ 中间件与三方包兼容）。</li>
<li>2023.12  新增 5+ 家公司真实使用，10+ Contributors 参与。</li>
</ul>
<br/>
<br/>
</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-602e76c3bdfe995632399d8611c22fa3">2 - 交流渠道</h1>
    
	<p>SOFAServerless 提供如下沟通交流渠道，欢迎加入我们一起分享、一起使用、一起收获：</p>
<h4 id="sofaserverless-社区交流与协作钉钉群24970018417">SOFAServerless 社区交流与协作钉钉群：24970018417</h4>
<p>如果您对 SOFAServerless 感兴趣、或者有初步意向使用 SOFAServerless、或者已经是 SOFAServerless / SOFAArk 的用户、或者有兴趣成为社区 Contributor，都可以加入该钉钉群和我们随时随地一起交流讨论、一起贡献代码。<br/>
<img width="200px" src="/img/dingtalk-qcode.png" /></p>
<h4 id="sofaserverless-用户微信群">SOFAServerless 用户微信群</h4>
<img width="200px" src="/img/wechat-qcode.png" />
<br/>
如果您对 SOFAServerless 感兴趣、或者有初步意向使用 SOFAServerless、或者已经是 SOFAServerless / SOFAArk 的用户，都可以加入该微信群随时随地一起交流讨论。<br/>
<br/>
<h4 id="社区双周会">社区双周会</h4>
<p><strong>每两周周二晚 19:30 - 20:30 会举办社区会议</strong>，下次社区双周会时间：2023 年 11 月 28 日 19:30 ~ 20:30，欢迎大家积极参与旁听或讨论。社区钉钉会议入会方式：<br />
入会链接：<a href="https://meeting.dingtalk.com/j/blp36k9mTbc">https://meeting.dingtalk.com/j/blp36k9mTbc</a><br />
钉钉会议号：90957500367<br />电话呼入：+867936169179 (中国大陆)、+867388953916 (中国大陆)<br />
<strong>具体会议时间也可关注社区钉钉协作群（群号：24970018417）</strong>。</p>
<br/>
<p>每个月底的周一会召开社区各组件 PMC 成员迭代规划会议，讨论并敲定下一个月需求规划。下次 PMC 成员月会时间：2023 年 11 月 27 日 19:30 ~ 20:30。入会方式同上。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-a473df27e2a59f4a48f7ec005f1be08d">3 - 贡献社区</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-2116f3408dfc680cc19d506d77f5894a">3.1 - 本地开发测试</h1>
    
	<h2 id="sofaark-和-arklet">SOFAArk 和 Arklet</h2>
<p>SOFAArk 是一个普通 Java SDK 项目，使用 Maven 作为依赖管理和构建工具，只需要本地安装 Maven 3.6 及以上版本即可正常开发代码和单元测试，无需其它的环境准备工作。<br />关于代码提交细节请参考：<a href="../first-pr">完成第一次 PR 提交</a>。</p>
<h2 id="modulecontroller">ModuleController</h2>
<p>ModuleController 是一个标准的 K8S Golang Operator 组件，里面包含了 ModuleDeployment Operator、ModuleReplicaSet Operator、Module Operator，在本地可以使用 minikube 做开发测试，具体请参考<a href="/docs/quick-start">本地快速开始</a>。<br />
编译构建请在 module-controller 目录下执行：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go mod download   <span style="color:#8f5902;font-style:italic"># if compile module-controller first time</span>
</span></span><span style="display:flex;"><span>go build -a -o manager cmd/main.go  
</span></span></code></pre></div><p>单元测试执行请在 module-controller 目录下执行：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>make <span style="color:#204a87">test</span>
</span></span></code></pre></div><p>您也可以使用 IDE 进行编译构建、开发调试和单元测试执行。<br />
module-controller 开发方式和标准 K8S Operator 开发方式完全一样，您可以参考 K8S Operator 开发<a href="https://kubernetes.io/zh-cn/docs/concepts/extend-kubernetes/operator/">官方文档</a>。</p>
<h2 id="arkctl">Arkctl</h2>
<p>Arkctl 是一个普通 Golang 项目，他是一个命令行工具集，包含了用户在本地开发和运维模块过程中的常用工具，它和普通 Golang 程序开发完全一样，<em>当前初始版本还在开发中</em>。</p>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-5726ff7fce2c3ff40a2cd82591c376cc">3.2 - 完成第一次 PR 提交</h1>
    
	<h2 id="认领或提交-issue">认领或提交 Issue</h2>
<p>不论您是修复 bug、新增功能或者改进现有功能，在您提交代码之前，请在 <a href="https://github.com/sofastack/sofa-serverless">SOFAServerless</a> 或 <a href="https://github.com/sofastack/sofa-ark">SOFAArk</a> GitHub 上认领一个 Issue 并将 Assignee 指定为自己（新人建议认领 <b>good-first-issue</b> 标签的新手任务）。或者提交一个新的 Issue，描述您要修复的问题或者要增加、改进的功能。这样做的好处是能避免与其他人的<strong>工作重复</strong>。</p>
<h2 id="获取源码">获取源码</h2>
<p>要修改或新增功能，在提 Issue 或者领取现有 Issue 后，点击左上角的<code>fork</code>按钮，复制一份 SOFAServerless 或 SOFAArk 主干代码到您的代码仓库。</p>
<h2 id="拉分支">拉分支</h2>
<p>SOFAServerless 和 SOFAArk 所有修改都在个人分支上进行，修改完后提交 <code>pull request</code>，当前在跑通 PR 流水线之后，会由相应组件的 PMC 或 Maintainer 负责 Review 与合并代码到主干（master）。因此，在 fork 源码后，您需要：</p>
<ul>
<li>下载代码到本地，这一步您可以选择 git/https 方式：</li>
</ul>
<pre tabindex="0"><code>git clone https://github.com/您的账号名/sofa-serverless.git
</code></pre><pre tabindex="0"><code>git clone https://github.com/您的账号名/sofa-ark.git
</code></pre><ul>
<li>拉分支准备修改代码：</li>
</ul>
<pre tabindex="0"><code>git branch add_xxx_feature
</code></pre><p><br />执行完上述命令后，您的代码仓库就切换到相应分支了。执行如下命令可以看到您当前分支：</p>
<pre tabindex="0"><code>  git branch -a
</code></pre><p>如果您想切换回主干，执行下面命令：</p>
<pre tabindex="0"><code>  git checkout -b master
</code></pre><p>如果您想切换回分支，执行下面命令：</p>
<pre tabindex="0"><code>  git checkout -b &#34;branchName&#34;
</code></pre><h2 id="修改代码提交到本地">修改代码提交到本地</h2>
<p>拉完分支后，就可以修改代码了。</p>
<h3 id="修改代码注意事项">修改代码注意事项</h3>
<ul>
<li>代码风格保持一致。SOFAServerless arklet 和 sofa-ark 通过 Maven 插件来保持代码格式一致，在提交代码前，务必先本地执行：</li>
</ul>
<pre tabindex="0"><code>mvn clean compile
</code></pre><p>module-controller 和 arkctl Golang 代码的格式化能力还在建设中。</p>
<ul>
<li>补充单元测试代码。</li>
<li>确保新修改通过所有单元测试。</li>
<li>如果是 bug 修复，应该提供新的单元测试来证明以前的代码存在 bug，而新的代码已经解决了这些 bug。对于 arklet 和 sofa-ark 您可以用如下命令运行所有测试：</li>
</ul>
<pre tabindex="0"><code>mvn clean test
</code></pre><p>对于 module-controller 和 arkctl，您可以用如下命令运行所有测试：</p>
<pre tabindex="0"><code>make test
</code></pre><p>也可以通过 IDE 来辅助运行。</p>
<h3 id="其它注意事项">其它注意事项</h3>
<ul>
<li>请保持您编辑的代码使用原有风格，尤其是空格换行等。</li>
<li>对于无用的注释，请直接删除。注释必须使用英文。</li>
<li>对逻辑和功能不容易被理解的地方添加注释。</li>
<li>务必第一时间更新 docs/content/zh-cn/ 目录中的 “docs”、“contribution-guidelines” 目录中的相关文档。</li>
</ul>
<p>修改完代码后，执行如下命令提交所有修改到本地：</p>
<pre tabindex="0"><code>git commit -am &#39;添加xx功能&#39;
</code></pre><h2 id="提交代码到远程仓库">提交代码到远程仓库</h2>
<p>在代码提交到本地后，就是与远程仓库同步代码了。执行如下命令提交本地修改到 github 上：</p>
<pre tabindex="0"><code>git push origin &#34;branchname&#34;
</code></pre><p>如果前面您是通过 fork 来做的，那么这里的 origin 是 push 到您的代码仓库，而不是 SOFAServerless 的代码仓库。</p>
<h2 id="提交合并代码到主干的请求">提交合并代码到主干的请求</h2>
<p>在的代码提交到 GitHub 后，您就可以发送请求来把您改好的代码合入 SOFAServerless 或 SOFAArk 主干代码了。此时您需要进入您的 GitHub 上的对应仓库，按右上角的 <code>pull request</code>按钮。选择目标分支，一般就是 <code>master</code>，当前需要选择组件的 <a href="../../role-and-promotion#member-list">Maintainer</a> 或 <a href="../../role-and-promotion#member-list">PMC</a> 作为 Code Reviewer，如果 PR 流水线校验和 Code Review 都通过，您的代码就会合入主干成为 SOFAServerless 的一部分。</p>
<h3 id="pr-流水线校验">PR 流水线校验</h3>
<p>PR 流水线校验包括：</p>
<ol>
<li>CLA 签署。第一次提交 PR 必须完成 CLA 协议的签署，如果打不开 CLA 签署页面请尝试使用代理。</li>
<li>自动为每个文件追加 Apache 2.0 License 声明和作者。</li>
<li>执行全部单元测试且必须全部通过。</li>
<li>检测覆盖率是否达到行覆盖 &gt;= 80%，分支覆盖 &gt;= 60%。</li>
<li>检测提交的代码是否存在安全漏洞。</li>
<li>检测提交的代码是否符合基本代码规范。</li>
</ol>
<p>以上校验必须全部通过，PR 流水线才会通过并进入到 Code Review 环节。</p>
<h3 id="code-review">Code Review</h3>
<p>当您选择对应组件的 <a href="../../role-and-promotion#member-list">Maintainer</a> 或 <a href="../../role-member-list#member-list">PMC</a> 作为 Code Reviewer 数天后，仍然没有人对您的提交给予任何回复，可以在 PR 下面留言并 at 相关人员，或者在社区钉钉协作群中（钉钉群号：24970018417）直接 at 相关人员 Review 代码。对于 Code Review 的意见，Code Reviewer 会直接备注到到对应的 PR 或者 Issue 中，如果您觉得建议是合理的，也请您把这些建议更新到您的代码中并重新提交 PR。</p>
<h3 id="合并代码到主干">合并代码到主干</h3>
<p>在 PR 流水线校验和 Code Review 都通过后，就由 SOFAServerless 维护人员操作合入主干了，代码合并之后您会收到合并成功的提示。</p>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-6c5458a163d621b3a719a2d5b3973530">3.3 - 文档、Issue、流程贡献</h1>
    
	<h2 id="文档贡献">文档贡献</h2>
<p>使用文档、技术文档、官网内容需要社区每一位 Contributor 共同维护，对任意文档和官网内容做出贡献的同学都是我们的 Contributor，并且根据活跃度有机会成为 SOFAServerless 组件的 Committer 甚至 PMC 成员，共同主导 SOFAServerless 的技术演进。<br/><br/></p>
<h2 id="issue-提交与回复贡献">Issue 提交与回复贡献</h2>
<p>任何使用过程中的问题、Bug、新功能、改进优化请创建 GitHub Issue，社区每天会有值班同学负责跟进 Issue。任何人提出或者回复 Issue 都是 SOFAServerless 的 Contributor，对回复 Issue 活跃的 Contributor 可以晋升为 Committer，如果特别活跃甚至可以晋升为 PMC 成员，共同主导 SOFAServerless 的技术演进。</p>
<h3 id="issue-模板">Issue 模板</h3>
<p>SOFAServerless（含 SOFAArk）Issue 有两种模板，一种是 “Question or Bug Report”，一种是 “Feature Request”。<br /><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/671/1694089517798-6930c476-c675-44c1-8e76-9f98166f0645.png#clientId=uab052d98-bf90-4&amp;from=paste&amp;height=182&amp;id=u345d4d11&amp;originHeight=364&amp;originWidth=2358&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=156188&amp;status=done&amp;style=none&amp;taskId=ufbd6f12c-1e4f-4de5-a74c-a951ddabfac&amp;title=&amp;width=1179" alt="image.png"></p>
<h3 id="question-or-bug-report">Question or Bug Report</h3>
<p>所有使用过程中遇到的问题或者疑似 Bug，请选择 “Question or Bug Report”，并提供详细的复现信息如下：</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Describe</span> <span style="color:#a40000">the</span> <span style="color:#a40000">question</span> <span style="color:#a40000">or</span> <span style="color:#a40000">bug</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">A</span> <span style="color:#a40000">clear</span> <span style="color:#a40000">and</span> <span style="color:#a40000">concise</span> <span style="color:#a40000">description</span> <span style="color:#a40000">of</span> <span style="color:#a40000">what</span> <span style="color:#a40000">the</span> <span style="color:#a40000">question</span> <span style="color:#a40000">or</span> <span style="color:#a40000">bug</span> <span style="color:#a40000">is.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Expected</span> <span style="color:#a40000">behavior</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">A</span> <span style="color:#a40000">clear</span> <span style="color:#a40000">and</span> <span style="color:#a40000">concise</span> <span style="color:#a40000">description</span> <span style="color:#a40000">of</span> <span style="color:#a40000">what</span> <span style="color:#a40000">you</span> <span style="color:#a40000">expected</span> <span style="color:#a40000">to</span> <span style="color:#a40000">happen.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Actual</span> <span style="color:#a40000">behavior</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">A</span> <span style="color:#a40000">clear</span> <span style="color:#a40000">and</span> <span style="color:#a40000">concise</span> <span style="color:#a40000">description</span> <span style="color:#a40000">of</span> <span style="color:#a40000">what</span> <span style="color:#a40000">actually</span> <span style="color:#a40000">happened.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Steps</span> <span style="color:#a40000">to</span> <span style="color:#a40000">reproduce</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">Steps</span> <span style="color:#a40000">to</span> <span style="color:#a40000">reproduce</span> <span style="color:#a40000">the</span> <span style="color:#a40000">problem:</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#a40000">.</span> <span style="color:#a40000">Go</span> <span style="color:#a40000">to</span> <span style="color:#a40000">&#39;...&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#0000cf;font-weight:bold">2</span><span style="color:#a40000">.</span> <span style="color:#a40000">Click</span> <span style="color:#a40000">on</span> <span style="color:#a40000">&#39;....&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#0000cf;font-weight:bold">3</span><span style="color:#a40000">.</span> <span style="color:#a40000">Scroll</span> <span style="color:#a40000">down</span> <span style="color:#a40000">to</span> <span style="color:#a40000">&#39;....&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#0000cf;font-weight:bold">4</span><span style="color:#a40000">.</span> <span style="color:#a40000">See</span> <span style="color:#a40000">error</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Screenshots</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">If</span> <span style="color:#a40000">applicable,</span> <span style="color:#a40000">add</span> <span style="color:#a40000">screenshots</span> <span style="color:#a40000">to</span> <span style="color:#a40000">help</span> <span style="color:#a40000">explain</span> <span style="color:#a40000">your</span> <span style="color:#a40000">problem.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Minimal</span> <span style="color:#a40000">yet</span> <span style="color:#a40000">complete</span> <span style="color:#a40000">reproducer</span> <span style="color:#a40000">code</span> <span style="color:#a40000">(or</span> <span style="color:#a40000">GitHub</span> <span style="color:#a40000">URL</span> <span style="color:#a40000">to</span> <span style="color:#a40000">code)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">###</span> <span style="color:#a40000">Environment</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">-</span> <span style="color:#a40000">SOFAArk</span> <span style="color:#a40000">version:</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">-</span> <span style="color:#a40000">JVM</span> <span style="color:#a40000">version</span> <span style="color:#a40000">(e.g.</span> <span style="color:#a40000">`java</span> <span style="color:#a40000">-version`):</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">-</span> <span style="color:#a40000">OS</span> <span style="color:#a40000">version</span> <span style="color:#a40000">(e.g.</span> <span style="color:#a40000">`uname</span> <span style="color:#a40000">-a`):</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">-</span> <span style="color:#a40000">Maven</span> <span style="color:#a40000">version:</span>
</span></span><span style="display:flex;"><span><span style="color:#a40000">-</span> <span style="color:#a40000">IDE</span> <span style="color:#a40000">version:</span>
</span></span></code></pre></div><h3 id="feature-request">Feature Request</h3>
<p>新功能、已有功能改进优化或者其它讨论，请选择 “Feature Request”。</p>
<h2 id="流程贡献">流程贡献</h2>
<p>SOFAServerless 当前制定了代码规约、PR 流程、CI 流水线、迭代管理、周会、交流渠道等各种协作规范，您可以对我们的协作规范和流程在 GitHub 上提出建议，即可成为我们的 Contributor。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-d890a1e9140aca7ee684208abba11a5f">3.4 - 组织会议和运营布道</h1>
    
	<p>我们鼓励大家宣传、布道 SOFAServerless，通过运营成为 SOFAServerless 的 Contributor、Committer 甚至 PMC，每一次 Contributor 的晋升，我们也会发放纪念品奖励。运营方式包括但不限于：</p>
<ol>
<li>在线上或线下技术会议、Meetup 中发表 SOFAServerless 的使用或者技术实现相关演讲。</li>
<li>与其他企业分享交流 SOFAServerless 的使用场景等。</li>
<li>在各种渠道发表关于 SOFAServerless 的使用或者技术实现相关文章或视频。</li>
<li>其它运营方式。</li>
</ol>
<br/>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-20720f61569788d3fa4a197db902e640">4 - 社区角色与晋升</h1>
    
	<h2 id="角色职责与晋升机制">角色职责与晋升机制</h2>
<p>SOFAServerless 社区角色参考了 Apache 开源产品组织方式，SOFAArk、Arklet、ModuleController、ArkCtl 每个组件都有各自的角色。每个组件的角色职责从低到高分别是：<strong>Contributor、Committer、PMC (Project Management Committee)、Maintainer</strong>。<br/></p>
<table>
<thead>
<tr>
<th>角色</th>
<th>责任与权限</th>
<th>晋升到更高角色机制</th>
</tr>
</thead>
<tbody>
<tr>
<td>Contributor</td>
<td>所有在社区提 <strong>Issue</strong>、回答 Issue、对外<strong>运营</strong>、提交<strong>文档</strong>内容或者提交任意<strong>代码</strong>的同学，都是相应组件的 <strong>Contributor</strong>。Contributor 拥有 Issue 提交、Issue 回复、官网或文档内容提交、代码提交（不包括代码评审）和对外发表文章权限。</td>
<td>当 Contributor 完成合并的代码或者文档内容足够多，就可以由该组件的 PMC 成员投票晋升为 Committer。当 Contributor 回答的 Issue 或者参与的运营活动足够多，也可以被 PMC 成员投票晋升为 Committer。</td>
</tr>
<tr>
<td>Committer</td>
<td>所有在社区积极回答 <strong>Issue</strong>、对外<strong>运营</strong>、提交<strong>文档</strong>内容或者提交<strong>代码</strong>的同学，按积极度都有可能被 PMC 成员投票晋升为 <strong>Committer</strong>。Committer 额外拥有代码<strong>评审</strong>、技术方案评审、Contributor <strong>培养</strong>的责任与权限。</td>
<td>对长期积极投入或持续有突出贡献的 Committer，经 PMC 成员投票可以晋升为相应组件的 PMC 成员。</td>
</tr>
<tr>
<td>PMC</td>
<td>对相应组件<strong>持续贡献</strong>且<strong>特别活跃</strong>的同学有机会晋升为 <strong>PMC</strong> 成员。PMC 成员额外拥有组件的 <strong>RoadMap</strong> 制定、技术<strong>方案</strong>和代码<strong>评审</strong>、Issue 和<strong>迭代管理</strong>、Contributor 和 Committer <strong>培养</strong>等责任与权限。</td>
<td></td>
</tr>
<tr>
<td>Maintainer</td>
<td>Maintainer 额外拥有密钥管理和仓库管理等管理员权限，除此之外在其他方面和 PMC 成员的责任与权限是<strong>完全对等</strong>的。</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="社区角色成员名单">社区角色成员名单</h2>
<h3 id="sofaark">SOFAArk</h3>
<h4 id="maintainer">Maintainer</h4>
<p>yuanyuancin<br />lvjing2</p>
<h4 id="pmc-project-management-comittee">PMC (Project Management Comittee)</h4>
<p>glmapper</p>
<h4 id="committer">Committer</h4>
<p>zjulbj5<br />gaosaroma<br />QilongZhang133<br />straybirdzls13<br />caojie0911</p>
<h4 id="contributor">Contributor</h4>
<p>lylingzhen10<br />khotyn<br />FlyAbner   （260+ 行提交，提名 Comitter？）<br />alaneuler<br />sususama<br />ujjboy<br />JoeKerouac<br />Lunarscave<br />HzjNeverStop<br />AiWu4Damon<br />vchangpengfei<br />HuangDayu<br />shenchao45<br />DalianRollingKing<br />nobodyiam<br />lanicc<br />azhsmesos<br />wuqian0808<br />KangZhiDong<br />suntao4019<br />huangyunbin<br />jiangyunpeng<br />michalyao<br />rootsongjc<br />Zwl0113<br />tofdragon<br />lishiguang4<br />hionwi<br />343585776<br />g-stream<br />zkitcast<br />davidzj<br />zyclove<br />WindSearcher<br />lovejin52022<br />smalljunHw<br />vchangpengfei<br />sq1015<br />xwh1108<br />yuanChina<br />blysin<br />yuwenkai666<br />hadoop835<br />gitYupan<br />thirdparty-core<br />Estom<br />jijuanwang<br />DCLe-DA<br />linkoog<br />springcoco<br />zhaowwwjian<br />xingcici<br />ixufeng<br />jnan806<br />lizhi12q<br />kongqq<br />wangxiaotao00<br />由于篇幅有限，23 年之前提交 Issue 的 Contributor 不在此一一列举，也同样感谢大家对 SOFAArk 的使用和咨询</p>
<h3 id="arklet">Arklet</h3>
<h4 id="maintainer-1">Maintainer</h4>
<p>yuanyuancin<br />lvjing2</p>
<h4 id="pmc-project-management-committee">PMC (Project Management Committee)</h4>
<p>TomorJM</p>
<h4 id="committer-1">Committer</h4>
<p>暂无</p>
<h4 id="contributor-1">Contributor</h4>
<p>glmapper<br />Lunarscave<br />lylingzhen</p>
<h3 id="modulecontroller">ModuleController</h3>
<h4 id="maintainer-2">Maintainer</h4>
<p>gold300jin</p>
<h4 id="pmc-project-management-committee-1">PMC (Project Management Committee)</h4>
<p>暂无</p>
<h4 id="committer-2">Committer</h4>
<p>暂无</p>
<h4 id="contributor-2">Contributor</h4>
<p>liu-657667<br />Charlie17Li<br />lylingzhen</p>
<h3 id="arkctl">Arkctl</h3>
<h4 id="maintainer-3">Maintainer</h4>
<p>yuanyuancin<br />lvjing2</p>
<h4 id="pmc-project-management-committee-2">PMC (Project Management Committee)</h4>
<p>暂无</p>
<h4 id="committer-3">Committer</h4>
<p>暂无</p>
<h4 id="contributor-3">Contributor</h4>
<p>暂无</p>
<br/>
</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-00e955e7b325b37beabf9dc83947c176">5 - SOFAArk 技术文档</h1>
    
	<p><a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-migration-guide/">SOFAArk 2.0 介绍</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-startup/">Ark 容器启动流程</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-plugin/">Ark 容器插件机制</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-classloader/">Ark 容器类加载机制</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-build-package-plugin/">打包插件源码解析</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-startup-process/">启动过程源码解析</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-dynamic-deploy/">动态热部署源码解析</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-class-loader-delegation/">类委托加载源码解析</a> <br/>
<a href="https://www.sofastack.tech/projects/sofa-boot/sofa-ark-multi-web-component-deploy/">多 Web 应用合并部署源码解析</a> <br/></p>
<br/>

</div>



    
      
  
  
  
  

  
  

  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-9ae993d6fa8ac20662cf30a0e33bd534">6 - Arklet 技术文档</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-44f8de035a733443de71918dd607b8ae">6.1 - Arklet 架构设计与接口设计</h1>
    
	<h1 id="概述">概述</h1>
<p>Arklet 为 SofaArk 基础和模块的交付提供了一个操作接口。有了 Arklet，Ark Biz 的发布和操作可以轻松灵活地进行。</p>
<p>Arklet 是由 <strong>ArkletComponent</strong> 内部构建的</p>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/11410549/a2740422-569e-4dd3-9c9a-1503996bd2f1" alt="image"></p>
<ul>
<li>ApiClient: 负责与外界交互的核心组件</li>
<li>CommandService: Arklet 对外暴露能力指令定义和扩展</li>
<li>OperationService: Ark Biz 与 SofaArk 交互，进行添加、删除、修改和封装基本能力</li>
<li>HealthService: 基于健康和稳定性，计算基础、Biz、系统等其他指标</li>
</ul>
<p>他们之间的协作如图所示
<img src="https://user-images.githubusercontent.com/11410549/266193839-7865e417-6909-4e89-bd48-c926162eaf83.jpg" alt="overview"></p>
<p>当然，您也可以通过实现 <strong>ArkletComponent</strong> 接口来扩展 Arklet 的组件功能</p>
<h1 id="命令扩展">命令扩展</h1>
<p>Arklet 外部公开了指令 API，并通过每个 API 映射的 CommandHandler 内部处理指令。</p>
<blockquote>
<p>CommandHandler 相关的扩展属于 CommandService 组件的统一管理</p>
</blockquote>
<p>您可以通过继承 <strong>AbstractCommandHandler</strong> 来自定义扩展命令</p>
<h2 id="内置命令-api">内置命令 API</h2>
<p>以下所有的指令 api 都使用 POST(application/json) 请求格式访问 arklet</p>
<p>启用了 http 协议，默认端口是 1238</p>
<blockquote>
<p>您可以设置 <code>sofa.serverless.arklet.http.port</code> JVM 启动参数覆盖默认端口</p>
</blockquote>
<h2 id="查询支持的命令">查询支持的命令</h2>
<ul>
<li>URL: 127.0.0.1:1238/help</li>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;query all ark biz(including master biz)&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;queryAllBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;list all supported commands&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;help&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;uninstall one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;uninstallBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;switch one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;switchBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;desc&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;install one ark biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&#34;id&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;installBiz&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="安装一个-biz">安装一个 biz</h2>
<ul>
<li>URL: 127.0.0.1:1238/installBiz</li>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#8f5902;font-style:italic">// local path should start with file://, alse support remote url which can be downloaded
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>    <span style="color:#204a87;font-weight:bold">&#34;bizUrl&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;file:///Users/jaimezhang/workspace/github/sofa-ark-dynamic-guides/dynamic-provider/target/dynamic-provider-1.0.0-ark-biz.jar&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例(成功):</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizInfos&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;declaredMode&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;identity&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider:1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;io.sofastack.dynamic.provider.ProviderApplication&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;priority&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#0000cf;font-weight:bold">100</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;provider&#34;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">],</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Install Biz: dynamic-provider:1.0.0 success, cost: 1092 ms, started at: 16:07:47,769&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>-输出样例(失败):</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;FAILED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;REPEAT_BIZ&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Biz: dynamic-provider:1.0.0 has been installed or registered.&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="卸载模块">卸载模块</h2>
<ul>
<li>URL: 127.0.0.1:1238/uninstallBiz</li>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><p>-输出样例(成功):</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例(失败):</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;FAILED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;NOT_FOUND_BIZ&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;message&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;Uninstall biz: test:1.0.0 not found.&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="switch-a-biz">Switch a biz</h2>
<ul>
<li>URL: 127.0.0.1:1238/switchBiz</li>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="查询所有-biz">查询所有 Biz</h2>
<ul>
<li>URL: 127.0.0.1:1238/queryAllBiz</li>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:[</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;dynamic-provider&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;io.sofastack.dynamic.provider.ProviderApplication&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;provider&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;stock-mng&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;mainClass&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;embed main&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span><span style="color:#4e9a06">&#34;/&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h2 id="查询健康状况">查询健康状况</h2>
<ul>
<li>URL: 127.0.0.1:1238/health</li>
</ul>
<p>以下根据不同的输入参数，获取到不同的状态信息</p>
<h3 id="查询健康状况-1">查询健康状况</h3>
<ul>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;healthData&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;jvm&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;max non heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">-9.5367431640625E-7</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;java version&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.8.0_331&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;max memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">885.5</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;max heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">885.5</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;used heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">137.14127349853516</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;used non heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">62.54662322998047</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;loaded class count&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">10063</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;init non heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">2.4375</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;total memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">174.5</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;free memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">37.358726501464844</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;unload class count&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;total class count&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">10063</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;committed heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">174.5</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;java home&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;****\\jre&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;init heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">64.0</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;committed non heap memory(M)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">66.203125</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;run time(s)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">34.432</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;cpu&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;count&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">4</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;total used (%)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">131749.0</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;****&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;user used (%)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">9.926451054656962</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;free (%)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">81.46475495070172</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;system used (%)&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">6.249762806548817</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;masterBizInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;/&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;bookstore-manager&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;pluginListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;artifactId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;web-ark-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;groupId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginActivator&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa.ark.web.embed.WebPluginActivator&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;web-ark-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginUrl&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;file:/****/2.2.3-SNAPSHOT/web-ark-plugin-2.2.3-20230901.090402-2.jar!/&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;2.2.3-SNAPSHOT&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;artifactId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;runtime-sofa-boot-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;groupId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginActivator&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa.runtime.ark.plugin.SofaRuntimeActivator&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;runtime-sofa-boot-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginUrl&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;file:/****/runtime-sofa-boot-plugin-3.11.0.jar!/&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;3.11.0&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">],</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;masterBizHealth&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;readinessState&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;ACCEPTING_TRAFFIC&#34;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;bookstore-manager&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;/&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="查询系统健康信息">查询系统健康信息</h3>
<ul>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;system&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#8f5902;font-style:italic">// [OPTIONAL] if metrics is null -&gt; query all system health info
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>  <span style="color:#204a87;font-weight:bold">&#34;metrics&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#4e9a06">&#34;cpu&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#4e9a06">&#34;jvm&#34;</span><span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;healthData&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;jvm&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;cpu&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//      &#34;masterBizHealth&#34;: {...}
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="查询模块健康信息">查询模块健康信息</h3>
<ul>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;biz&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#8f5902;font-style:italic">// [OPTIONAL] if moduleName is null and moduleVersion is null -&gt; query all biz
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>  <span style="color:#204a87;font-weight:bold">&#34;moduleName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;bookstore-manager&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#8f5902;font-style:italic">// [OPTIONAL] if moduleVersion is null -&gt; query all biz named moduleName
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>  <span style="color:#204a87;font-weight:bold">&#34;moduleVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;healthData&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;bizInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;bookstore-manager&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizState&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;ACTIVATED&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;1.0.0&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;webContextPath&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;/&#34;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//      &#34;bizListInfo&#34;: [
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//        {
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//          &#34;bizName&#34;: &#34;bookstore-manager&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//          &#34;bizState&#34;: &#34;ACTIVATED&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//          &#34;bizVersion&#34;: &#34;1.0.0&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//          &#34;webContextPath&#34;: &#34;/&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//        }
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">//      ]
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="查询插件健康信息">查询插件健康信息</h3>
<ul>
<li>输入样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;type&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#8f5902;font-style:italic">// [OPTIONAL] if moduleName is null -&gt; query all biz
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>  <span style="color:#204a87;font-weight:bold">&#34;moduleName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;web-ark-plugin&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><ul>
<li>输出样例:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;SUCCESS&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>  <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;healthData&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>      <span style="color:#204a87;font-weight:bold">&#34;pluginListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">{</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;artifactId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;web-ark-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;groupId&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginActivator&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;com.alipay.sofa.ark.web.embed.WebPluginActivator&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginName&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;web-ark-plugin&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginUrl&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;file:/****/web-ark-plugin-2.2.3-20230901.090402-2.jar!/&#34;</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>          <span style="color:#204a87;font-weight:bold">&#34;pluginVersion&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;2.2.3-SNAPSHOT&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#000;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span>  <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><h3 id="使用端点查询健康状况">使用端点查询健康状况</h3>
<p>使用端点获取 k8s 模块的健康信息</p>
<p><strong>默认配置</strong></p>
<ul>
<li>端点暴露包括：<code>*</code></li>
<li>端点基本路径：<code>/</code></li>
<li>端点服务器端口：<code>8080</code></li>
</ul>
<p><strong>http 代码结果</strong></p>
<ul>
<li><code>HEALTHY(200)</code>：如果所有健康指标都是健康的，获取健康信息</li>
<li><code>UNHEALTHY(400)</code>：一旦健康指标不健康，获取健康信息</li>
<li><code>ENDPOINT_NOT_FOUND(404)</code>：找不到端点路径或参数</li>
<li><code>ENDPOINT_PROCESS_INTERNAL_ERROR(500)</code>：获取健康过程中抛出错误</li>
</ul>
<h3 id="查询所有健康信息">查询所有健康信息</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl 127.0.0.1:8080/arkletHealth
</span></span></code></pre></div><ul>
<li>输出样例</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>   
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;healthy&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">200</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;codeType&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;HEALTHY&#34;</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;jvm&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;masterBizHealth&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;cpu&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;masterBizInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;bizListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">],</span>        
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&#34;pluginListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">]</span>    
</span></span><span style="display:flex;"><span>    <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>  
</span></span></code></pre></div><h3 id="查询所有-bizplugin-健康信息">查询所有 biz/plugin 健康信息</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl: 127.0.0.1:8080/arkletHealth/<span style="color:#ce5c00;font-weight:bold">{</span>moduleType<span style="color:#ce5c00;font-weight:bold">}</span> <span style="color:#ce5c00;font-weight:bold">(</span>moduleType 必须在 <span style="color:#ce5c00;font-weight:bold">[</span><span style="color:#4e9a06">&#39;biz&#39;</span>, <span style="color:#4e9a06">&#39;plugin&#39;</span><span style="color:#ce5c00;font-weight:bold">]</span> 中<span style="color:#ce5c00;font-weight:bold">)</span>
</span></span></code></pre></div><ul>
<li>输出样例</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>   
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;healthy&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">200</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;codeType&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;HEALTHY&#34;</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>        
</span></span><span style="display:flex;"><span>       <span style="color:#204a87;font-weight:bold">&#34;bizListInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">[</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">],</span>  
</span></span><span style="display:flex;"><span>       <span style="color:#8f5902;font-style:italic">// &#34;pluginListInfo&#34;: [...]      
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>   <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>  
</span></span></code></pre></div><h3 id="查询单个-bizplugin-健康信息">查询单个 biz/plugin 健康信息</h3>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl 127.0.0.1:8080/arkletHealth/<span style="color:#ce5c00;font-weight:bold">{</span>moduleType<span style="color:#ce5c00;font-weight:bold">}</span>/moduleName/moduleVersion <span style="color:#ce5c00;font-weight:bold">(</span>moduleType must in <span style="color:#ce5c00;font-weight:bold">[</span><span style="color:#4e9a06">&#39;biz&#39;</span>, <span style="color:#4e9a06">&#39;plugin&#39;</span><span style="color:#ce5c00;font-weight:bold">])</span>
</span></span></code></pre></div><ul>
<li>输出样例：</li>
</ul>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#000;font-weight:bold">{</span>   
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;healthy&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">,</span>
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;code&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#0000cf;font-weight:bold">200</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;codeType&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;HEALTHY&#34;</span><span style="color:#000;font-weight:bold">,</span>    
</span></span><span style="display:flex;"><span>   <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span>        
</span></span><span style="display:flex;"><span>       <span style="color:#204a87;font-weight:bold">&#34;bizInfo&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000;font-weight:bold">{</span><span style="color:#a40000">...</span><span style="color:#000;font-weight:bold">},</span>  
</span></span><span style="display:flex;"><span>       <span style="color:#8f5902;font-style:italic">// &#34;pluginInfo&#34;: {...}      
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>   <span style="color:#000;font-weight:bold">}</span>
</span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span>
</span></span></code></pre></div><br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-ca0da12fe622ea86b46a675b1cf7ff9e">6.2 - 如何发布 Arklet 版本</h1>
    
	<h3 id="触发-github-action-发布到-snapshot-staging">触发 github Action 发布到 snapshot staging</h3>
<p>版本发布到 maven 中央仓库，发布能力集成到了 github action 里：<br />
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1694917403997-feefe1c0-9aff-440c-afca-58f7dce10c19.png#clientId=u0869f56c-af1d-4&amp;from=paste&amp;height=469&amp;id=u1538d344&amp;originHeight=938&amp;originWidth=2114&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=193270&amp;status=done&amp;style=none&amp;taskId=u851fd385-a349-4f24-a37a-ded4c025441&amp;title=&amp;width=1057" alt="image.png"></p>
<p><strong>该 action 需要手动触发执行</strong>：<br />
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1694917427074-e50ce7a6-44f7-4f7b-abc8-f78142727b28.png#clientId=u0869f56c-af1d-4&amp;from=paste&amp;height=283&amp;id=u51c5094e&amp;originHeight=566&amp;originWidth=1004&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=55468&amp;status=done&amp;style=none&amp;taskId=u83b68510-dcdd-4dae-9ab1-c1d2d7b34df&amp;title=&amp;width=502" alt="image.png"><br />
执行成功后，只会发布到 snapshot staging，如果是 SNAPSHOT 版本，则这里执行完就可以结束。如果是正式版本，发布到 snapshot staging 之后，还需要推送到 release staging。</p>
<h3 id="发布到-release-staging">发布到 Release staging</h3>
<p>打开  <a href="https://oss.sonatype.org">https://oss.sonatype.org</a> ，点击右上角的 Log In, 登陆信息可找管理员。<br />
点击左侧的 Staging Repositories：<br />
<img src="https://gw.alipayobjects.com/zos/skylark/4f0bacb1-599d-4a3b-90f4-8d88bba2f660/2018/png/d27b8f43-c7eb-41a9-a9c4-49b0308c44d8.png#height=250&amp;id=kxutu&amp;originHeight=431&amp;originWidth=1294&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=752" alt=""></p>
<p>搜索刚才记录的 ID：<br />
<img src="https://gw.alipayobjects.com/zos/skylark/2c91c79e-fce1-4483-8c35-c712d5367805/2018/png/ae5425f2-a572-4c50-9307-fd9618286689.png#height=394&amp;id=O3wmg&amp;originHeight=749&amp;originWidth=1428&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=752" alt=""></p>
<p>钩上之后就可以进行 Release (发布) 或者 Drop (放弃) 的操作。</p>
<p><strong>当看不到这两个选项，只有 Close 选项时，则先选择 Close 操作，这时候如果包没有问题，则接下来可以 Release 或者 Drop。如果有问题，下面的内容中的 Activity 中会显示包不能正常 Close 的原因, 按照提示进行修改就可以了。</strong></p>
<h3 id="仓库包同步与搜索">仓库包同步与搜索</h3>
<p>在包发布到 release 仓库之后， 10 分钟后包会更新，在 <a href="http://central.maven.org/maven2/com/alipay/sofa/">http://central.maven.org/maven2/com/alipay/sofa/</a> 能看到包。2 小时之后，可通过 <a href="http://search.maven.org/">搜索</a> 查询到包。</p>
<br/>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-9f7246557f3988e5591410a2c92f379e">7 - ModuleController 技术文档</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-72b8455792d08674da639fa21b8e66ae">7.1 - ModuleController 架构设计</h1>
    
	<h2 id="介绍">介绍</h2>
<p>ModuleController 是一个 K8S 控制器，该控制器参考 K8S 架构，定义并且实现了 ModuleDeployment、ModuleReplicaSet、Module 等核心模型与调和能力，从而实现了 Serverless 模块的秒级运维调度，以及与基座的联动运维能力。</p>
<h2 id="基本架构">基本架构</h2>
<p>ModuleController 目前包含 ModuleDeployment Opertor、ModuleReplicaSet Operator、Module Operator 三个组件。和 K8S 原生 Deployment 类似，<strong>用户创建 ModuleDeployment 会调和出 ModuleReplicaSet，ModuleReplicaSet 会进一步调和出 Module，最终 Module Operator 会调用 Pod 里的 Arklet SDK 去安装或卸载模块</strong>。此外 ModuleController 还会为 ModuleDeployment 自动生成 K8S Service，企业可以监听该 Service 的 IP 变化实现与自身流量控制系统的集成，从而实现模块粒度的切流和挂流。<br />
<a href="architecture.png"><img src="../architecture.png#from=url&amp;height=536&amp;id=ZnBYG&amp;originHeight=502&amp;originWidth=645&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=689" alt=""></a></p>
<h2 id="功能清单和-roadmap">功能清单和 RoadMap</h2>
<ul>
<li><strong>08.15：0.2 版本</strong>上线（包括非对等模块发布、卸载、扩缩容、副本保持、基座运维联动）</li>
<li><strong>08.25：0.3 版本</strong>上线（包括回滚链路、各项参数校验、单测达到 80/60、CI 自动化、开发者指南）</li>
<li><strong>09.31：0.5 版本</strong>上线（1:1 先扩后缩、模块回滚、两种调度策略、状态回流、1+ 端到端集成测试）</li>
<li><strong>10.30：0.6 版本</strong>上线（支持以 K8S Service 方式联动企业四七层流量控制、总计 10+ 端到端集成测试）</li>
<li><strong>11.30：1.0 版本</strong>上线（支持对等发布运维、各项修复打磨、总计 20+ 端到端集成测试）</li>
<li><strong>12.30：1.1 版本</strong>上线（支持模块和基座自动弹性伸缩、对等与非对等发布运维能力完善）</li>
</ul>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-be4b5c4491d910c089a03f3bd6b4ec7b">7.2 - CRD 模型设计</h1>
    
	<h2 id="crd-模型对比">CRD 模型对比</h2>
<table>
<thead>
<tr>
<th>K8S 原生 CRD</th>
<th>ModuleController CRD</th>
<th>关系和区别</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pod</td>
<td>Module</td>
<td>Pod：K8S 中创建和管理的、最小的可部署的计算单元。     Module：Serverless 创建和管理的、最小的可部署的计算单元。</td>
</tr>
<tr>
<td>PodSpec</td>
<td>ModuleSpec</td>
<td>PodSpec：对 Pod 的描述。包含容器、调度、卷等。     ModuleSpec：对 Module 的描述，包含模块、服务、调度（亲和性）。</td>
</tr>
<tr>
<td>PodTemplate</td>
<td>ModuleTemplate</td>
<td>PodTemplate：定义 Pod 的生成副本，包含 PodSpec。     ModuleTemplate：定义 Module 的生成副本，包含 ModuleGroupSpec。</td>
</tr>
<tr>
<td>Deployment</td>
<td>ModuleDeployment</td>
<td>Deployment：定义 Pod 的期望状态和副本数量。     ModuleDeployment：定义 Module 的期望状态和副本数量。</td>
</tr>
<tr>
<td>ReplicaSet</td>
<td>ModuleReplicaSet</td>
<td>ReplicaSet：管理 Pod 的运行副本。     <br />ModuleReplicaSet：管理 Module 的运行副本。</td>
</tr>
</tbody>
</table>
<h2 id="moduledeployment-crd-模型">ModuleDeployment CRD 模型</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/863d8ede-4904-423e-9473-77466af33c46" alt="image"></p>
<h2 id="module-crd-模型">Module CRD 模型</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/f4e109eb-4b10-4835-a502-7d723b1ca73c" alt="image"></p>
<h2 id="moduletemplate-crd-模型">ModuleTemplate CRD 模型</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/db4fd36b-d698-4946-8d62-6e6651d3f18a" alt="image"></p>
<h2 id="modulereplicaset-crd-模型">ModuleReplicaSet CRD 模型</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/13fbf29e-3977-4138-b3dd-849ce871fb3b" alt="image"></p>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-339ad39102ec6d572f675d168eb0a6c2">7.3 - 核心代码结构</h1>
    
	<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/671/1694002853387-dfb011bb-b443-401d-b6b2-0e2d89d9ca38.png#clientId=u9331e04a-ec01-4&amp;from=paste&amp;height=733&amp;id=u434d34f6&amp;originHeight=1466&amp;originWidth=2236&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=746447&amp;status=done&amp;style=none&amp;taskId=u60bb866c-f80f-4cda-b668-d41bdef0f7b&amp;title=&amp;width=1118" alt="image.png"></p>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/671/1694002891414-adf2f622-38ec-46cb-8f73-4ae6efdd87ab.png#clientId=u9331e04a-ec01-4&amp;from=paste&amp;height=107&amp;id=u798a320c&amp;originHeight=214&amp;originWidth=612&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=53871&amp;status=done&amp;style=none&amp;taskId=u47639d5b-c3d6-4356-800a-789e9f2791c&amp;title=&amp;width=306" alt="image.png"></p>
<br/>
<p>核心代码逻辑在 moduledeployment_controller.go、modulereplicaset_controller.go、module_controller.go、controller_utils.go，里面有详细注释。</p>
<br/>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-de7e40f637d5e11c931b8c9e41910f4d">7.4 - 模块生命周期</h1>
    
	<h3 id="模块生命周期">模块生命周期</h3>
<p>4象限描述了模块的生命周期： Prepare、Upgrading、Completed、Available</p>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/16ec7808-eab9-4293-b9c2-cddda3de5d85" alt="image"></p>
<h3 id="模块状态机">模块状态机</h3>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/d06c10d6-1d37-48a9-9af3-0d44a6d7e1fd" alt="image"></p>
<br/>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-4c6a73428cd292db6a65b7e3740abdd4">7.5 - 核心流程时序图</h1>
    
	<h2 id="模块首发">模块首发</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/d449f851-d989-4221-8809-f39a786529af" alt="image"></p>
<h2 id="模块二发">模块二发</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/1f649f5e-b8bd-458c-ba9d-333ed1fad46c" alt="image"></p>
<h2 id="模块下线">模块下线</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/867c16a3-a3a8-4ace-b132-0051bd2ba0ad" alt="image"></p>
<h2 id="对等基座扩容">对等基座扩容</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/c0db1f13-0ec8-43b4-a24e-7b8677405a15" alt="image"></p>
<h2 id="对等基座缩容">对等基座缩容</h2>
<p><img src="https://github.com/sofastack/sofa-serverless/assets/13743483/7e950729-08dd-4264-aa25-0ddfa6828b79" alt="image">
<br/></p>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-db0fd3436760ca9f36ce5775358861d3">8 - Arkctl 技术文档</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-17a1474bf0b4f08b2afd73c908fb081d">8.1 - Arkctl 技术文档</h1>
    
	<p>Arkctl 是一个普通 Golang 项目，他是一个命令行工具集，包含了用户在本地开发和运维模块过程中的常用工具，它和普通 Golang 程序开发完全一样，<em>当前初始版本还在开发中</em>。</p>
<br/>

</div>



    
	
  

    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-c5379127fb28ac273198b2c05d133831">9 - 多模块运行时适配或最佳实践</h1>
    
	
</div>



    
      
  
  
  
  

  
  

  
    
    
	
    

<div class="td-content" style="">
    
	<h1 id="pg-e8336cb2ec84a57eea63b09a2d517063">9.1 - log4j2 的多模块化适配</h1>
    
	<h2 id="为什么需要做适配">为什么需要做适配</h2>
<p>原生 log4j2 在多模块下，模块没有独立打印的日志目录，统一打印到基座目录里，导致日志和对应的监控无法隔离。这里做适配的目的就是要让模块能有独立的日志目录。</p>
<h2 id="普通应用-log4j2-的初始化">普通应用 log4j2 的初始化</h2>
<p>在 Spring 启动前，log4j2 会使用默认值初始化一次各种 logContext 和 Configuration，然后在 Spring 启动过程中，监听 Spring 事件进行初始化
<code>org.springframework.boot.context.logging.LoggingApplicationListener</code>，这里会调用到 Log4j2LoggingSystem.initialize 方法</p>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1696930949183-9519451c-be76-4d9b-bb6b-28a1b21e7fa7.png" alt=""></p>
<p>该方法会根据 loggerContext 来判断是否已经初始化过了</p>
<blockquote>
<p>这里在多模块下会存在问题一</p>
<p>这里的 getLoggerContext 是根据 org.apache.logging.log4j.LogManager 所在 classLoader 来获取 LoggerContext。根据某个类所在 ClassLoader 来提取 LoggerContext 在多模块化里会存在不稳定，因为模块一些类可以设置为委托给基座加载，所以模块里启动的时候，可能拿到的 LoggerContext 是基座的，导致这里 isAlreadyInitialized 直接返回，导致模块的 log4j2 日志无法进一步根据用户配置文件配置。</p>
</blockquote>
<p>如果没初始化过，则会进入 super.initialize, 这里需要做两部分事情：</p>
<ol>
<li>获取到日志配置文件</li>
<li>解析日志配置文件里的变量值
这两部分在多模块里都可能存在问题，先看下普通应用过程是如何完成这两步的</li>
</ol>
<h3 id="获取日志配置文件">获取日志配置文件</h3>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1696931678652-81a19dc2-f618-48b0-add3-d098d3781966.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0" alt=""></p>
<p>可以看到是通过 ResourceUtils.getURL 获取的 location 对应日志配置文件的 url，这里通过获取到当前线程上下文 ClassLoader 来获取 URL，这在多模块下没有问题（因为每个模块启动时线程上下文已经是 模块自身的 ClassLoader ）。</p>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1696931908899-f1fac1bb-f365-49f9-81a2-3e2d924c2b7d.png?x-oss-process=image%2Fresize%2Cw_1500%2Climit_0" alt=""></p>
<h3 id="解析日志配置值">解析日志配置值</h3>
<p>配置文件里有一些变量，例如这些变量</p>
<p><img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1696932148670-d04bde21-e46b-476c-9cf5-53e43cc4dbe2.png" alt=""></p>
<p>这些变量的解析逻辑在 <code>org.apache.logging.log4j.core.lookup.AbstractLookup</code> 的具体实现里，包括</p>
<table>
<thead>
<tr>
<th></th>
<th>变量写法</th>
<th>代码逻辑地址</th>
</tr>
</thead>
<tbody>
<tr>
<td>${bundle:application:logging.file.path}</td>
<td>org.apache.logging.log4j.core.lookup.ResourceBundleLookup</td>
<td>根据 ResourceBundleLookup 所在 ClassLoader 提前到 application.properties, 读取里面的值</td>
</tr>
<tr>
<td>${ctx:logging.file.path}</td>
<td>org.apache.logging.log4j.core.lookup.ContextMapLookup</td>
<td>根据 LoggerContext 上下文 ThreadContex 存储的值来提起，这里需要提前把 applicaiton.properties 的值设置到 ThreadContext 中</td>
</tr>
</tbody>
</table>
<p>根据上面判断通过 bundle 的方式配置在多模块里不可行，因为 ResourceBundleLookup 可能只存在于基座中，导致始终只能拿到基座的 application.properties，导致模块的日志配置路径与基座相同，模块日志都打到基座中。所以需要改造成使用 ContextMapLookup。</p>
<h2 id="预期多模块合并下的日志">预期多模块合并下的日志</h2>
<p>基座与模块都能使用独立的日志配置、配置值，完全独立。但由于上述分析中，存在两处可能导致模块无法正常初始化的逻辑，故这里需要多 log4j2 进行适配。</p>
<h3 id="多模块适配点">多模块适配点</h3>
<ol>
<li>
<p>getLoggerContext() 能拿到模块自身的 LoggerContext
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1696938182575-51ce1066-21f0-47bb-8bdb-c3c7d0814ca3.png" alt=""></p>
</li>
<li>
<p>需要调整成使用 ContextMapLookup，从而模块日志能获取到模块应用名，日志能打印到模块目录里</p>
<p>a. 模块启动时将 application.properties 的值设置到 ThreadContext 中
b. 日志配置时，只能使用 ctx:xxx:xxx 的配置方式</p>
</li>
</ol>
<h2 id="模块改造方式">模块改造方式</h2>
<p><a href="https://github.com/sofastack/sofa-serverless/tree/master/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2/src/main/java/com/alipay/sofa/serverless/log4j2">详细查看源码</a></p>

</div>



    
	
  
    
    
	
    

<div class="td-content" style="page-break-before: always">
    
	<h1 id="pg-fce299658e201c9a561eaab5974c0199">9.2 - ehcache 的多模块化最佳实践</h1>
    
	<h2 id="为什么需要最佳实践">为什么需要最佳实践</h2>
<p>CacheManager 初始化的时候存在共用 static 变量，多应用使用相同的 ehcache name，导致缓存互相覆盖。</p>
<h2 id="最佳实践的几个要求">最佳实践的几个要求</h2>
<ol>
<li>基座里必须引入 ehcache，模块里复用基座</li>
</ol>
<p>在 springboot 里 ehcache 的初始化需要通过 Spring 里定义的 EhCacheCacheConfiguration 来创建，由于 EhCacheCacheConfiguration 是属于 Spring, Spring 统一放在基座里。
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700202934067-7a0d74b7-b765-4c96-ab95-6189602235b8.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=679&amp;id=u3a86e2ae&amp;originHeight=1358&amp;originWidth=2284&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=801737&amp;status=done&amp;style=none&amp;taskId=ub2119003-e3dd-4276-83a3-bc0a8598185&amp;title=&amp;width=1142" alt="image.png"></p>
<p>这里在初始化的时候，在做 Bean 初始化的条件判断时会走到类的检验，
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700203147758-c2f4f211-27b1-408a-8a59-04b54a0602f3.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=532&amp;id=ea4Xj&amp;originHeight=1064&amp;originWidth=1052&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=607056&amp;status=done&amp;style=none&amp;taskId=u59dc4240-37cd-4a97-8b57-0e71250149b&amp;title=&amp;width=526" alt="image.png">
如果 net.sf.ehcache.CacheManager 是。这里会走到 java native 方法上做判断，从当前类所在的 ClassLoader 里查找 net.sf.ehcache.CacheManager 类，所以基座里必须引入这个依赖，否则会报 ClassNotFound 的错误。
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700203220867-62f2b7be-e853-488c-a6bc-a95c874793f1.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=97&amp;id=u3ca967f5&amp;originHeight=194&amp;originWidth=1798&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=104469&amp;status=done&amp;style=none&amp;taskId=u4957f800-31ee-40b3-bb09-487b9ab16ba&amp;title=&amp;width=899" alt="image.png"></p>
<ol start="2">
<li>模块里将引入的 ehcache 排包掉（scope设置成 provide，或者使用自动瘦身能力）</li>
</ol>
<p>模块使用自己 引入的 ehcache，照理可以避免共用基座 CacheManager 类里的 static 变量，而导致报错的问题。但是实际测试发现，模块安装的时候，在初始化 enCacheCacheManager 时，
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700203897715-c9f97922-b466-4e73-8319-1a0f5ec3cc73.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=211&amp;id=uaa50406f&amp;originHeight=422&amp;originWidth=2048&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=235120&amp;status=done&amp;style=none&amp;taskId=ub3d92b21-fec0-4462-92ad-91449dcea2d&amp;title=&amp;width=1024" alt="image.png">
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700203915265-f42253e4-1ff4-4088-a87e-8b6e063540ba.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=107&amp;id=uedd0a010&amp;originHeight=214&amp;originWidth=1258&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=101140&amp;status=done&amp;style=none&amp;taskId=u044240e0-fe55-4f77-b63e-41ebf9eca47&amp;title=&amp;width=629" alt="image.png">
这里在 new 对象时，需要先获得对象所属类的 CacheManager 是基座的 CacheManager。这里也不能讲 CacheManager 由模块 compile 引入，否则会出现一个类由多个不同 ClassLoader 引入导致的问题。
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700212320690-8112f0f7-7ab7-48a7-8d9d-95aa3d49492a.png#clientId=u4cdbd480-e8bb-4&amp;from=paste&amp;height=145&amp;id=ud90248f9&amp;originHeight=290&amp;originWidth=2736&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=294518&amp;status=done&amp;style=none&amp;taskId=ue9c723ea-0a3b-4854-b069-402238e5fcd&amp;title=&amp;width=1368" alt="image.png"></p>
<p>所以结论是，这里需要全部委托给基座加载。</p>
<h2 id="最佳实践的方式">最佳实践的方式</h2>
<ol>
<li>模块 ehcache 排包瘦身委托给基座加载</li>
<li>如果多个模块里有多个相同的 cacheName，需要修改 cacheName 为不同值。</li>
<li>如果不想改代码的方式修改 cache name，可以通过打包插件的方式动态替换 cacheName</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">&lt;plugin&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;groupId&gt;</span>com.google.code.maven-replacer-plugin<span style="color:#204a87;font-weight:bold">&lt;/groupId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;artifactId&gt;</span>replacer<span style="color:#204a87;font-weight:bold">&lt;/artifactId&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;version&gt;</span>1.5.3<span style="color:#204a87;font-weight:bold">&lt;/version&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;executions&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#8f5902;font-style:italic">&lt;!-- 打包前进行替换 --&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;execution&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;phase&gt;</span>prepare-package<span style="color:#204a87;font-weight:bold">&lt;/phase&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;goals&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;goal&gt;</span>replace<span style="color:#204a87;font-weight:bold">&lt;/goal&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/goals&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/execution&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/executions&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;configuration&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#8f5902;font-style:italic">&lt;!-- 自动识别到项目target文件夹 --&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;basedir&gt;</span>${build.directory}<span style="color:#204a87;font-weight:bold">&lt;/basedir&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#8f5902;font-style:italic">&lt;!-- 替换的文件所在目录规则 --&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;includes&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;include&gt;</span>classes/j2cache/*.properties<span style="color:#204a87;font-weight:bold">&lt;/include&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/includes&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;replacements&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;replacement&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;token&gt;</span>ehcache.ehcache.name=f6-cache<span style="color:#204a87;font-weight:bold">&lt;/token&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#204a87;font-weight:bold">&lt;value&gt;</span>ehcache.ehcache.name=f6-${parent.artifactId}-cache<span style="color:#204a87;font-weight:bold">&lt;/value&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#204a87;font-weight:bold">&lt;/replacement&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#204a87;font-weight:bold">&lt;/replacements&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#204a87;font-weight:bold">&lt;/configuration&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">&lt;/plugin&gt;</span>
</span></span></code></pre></div><ol start="4">
<li>需要把 FactoryBean 的 shared 设置成 false</li>
</ol>
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#5c35cc;font-weight:bold">@Bean</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">EhCacheManagerFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ehCacheManagerFactoryBean</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">EhCacheManagerFactoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">factoryBean</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">EhCacheManagerFactoryBean</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// 需要把 factoryBean 的 share 属性设置成 false</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">factoryBean</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setShared</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#8f5902;font-style:italic">//        factoryBean.setShared(false);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">factoryBean</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setCacheManagerName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;biz1EhcacheCacheManager&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">factoryBean</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">setConfigLocation</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ClassPathResource</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;ehcache.xml&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">return</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">factoryBean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p>否则会进入这段逻辑，初始化 CacheManager 的static 变量 instance. 该变量如果有值，且如果模块里 shared 也是ture 的化，就会重新复用 CacheManager 的 instance，从而拿到基座的 CacheManager, 从而报错。
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700360794825-3f7f4a63-22bc-49ea-81d1-83bd94804087.png#clientId=u2481e0c2-f328-4&amp;from=paste&amp;height=399&amp;id=u7432be71&amp;originHeight=798&amp;originWidth=1596&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=422965&amp;status=done&amp;style=none&amp;taskId=u1e450639-4846-4b6a-9862-bac787ae8e5&amp;title=&amp;width=798" alt="image.png">
<img src="https://intranetproxy.alipay.com/skylark/lark/0/2023/png/149473/1700359643422-7b252689-7e0c-41f3-995e-cbc40726136e.png#clientId=u2481e0c2-f328-4&amp;from=paste&amp;height=161&amp;id=u80efa85e&amp;originHeight=322&amp;originWidth=2426&amp;originalType=binary&amp;ratio=2&amp;rotation=0&amp;showTitle=false&amp;size=339519&amp;status=done&amp;style=none&amp;taskId=u15aeda8f-e089-4bf0-8bc7-e47eff9d2f0&amp;title=&amp;width=1213" alt="image.png"></p>
<h2 id="最佳实践的样例">最佳实践的样例</h2>
<p>样例工程请<a href="https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/cache/ehcache">参考这里</a></p>

</div>



    
	
  

    
	
  



          </main>
        </div>
      </div>
      <footer class="td-footer row d-print-none">
  <div class="container-fluid">
    <div class="row mx-md-2">
      <div class="col-6 col-sm-4 text-xs-center order-sm-2">
        
        
        
<ul class="td-footer__links-list">
  
  <li class="td-footer__links-item" data-bs-toggle="tooltip" title="通过社区交流群" aria-label="通过社区交流群">
    <a target="_blank" rel="noopener" href="/docs/contribution-guidelines/communication-channel/" aria-label="通过社区交流群">
      <i class="fab fa-twitter"></i>
    </a>
  </li>
  
</ul>

        
        
      </div>
      <div class="col-6 col-sm-4 text-end text-xs-center order-sm-3">
        
        
        
<ul class="td-footer__links-list">
  
  <li class="td-footer__links-item" data-bs-toggle="tooltip" title="看这里" aria-label="看这里">
    <a target="_blank" rel="noopener" href="/docs/contribution-guidelines/contribution/first-pr/" aria-label="看这里">
      <i class="fab fa-github"></i>
    </a>
  </li>
  
</ul>

        
        
      </div>
      <div class="td-footer__copyright-etc col-12 col-sm-4 text-center py-2 order-sm-2">
        <span>&copy; 2023 SOFAServerless 开源社区 保留所有权利</span>
        
        
      </div>
    </div>
  </div>
</footer>
    </div>
    
  <script src="/js/main.min.1eb4262674b2d02aa8d18559fef13b166dbdfa627fd0a495c66e11577c026aa3.js" integrity="sha256-HrQmJnSy0Cqo0YVZ/vE7Fm29&#43;mJ/0KSVxm4RV3wCaqM=" crossorigin="anonymous"></script>
<script src='/js/prism.js'></script>
<script src='/js/tabpane-persist.js'></script>

  </body>
</html>
